import re

from django.contrib.auth import authenticate, login, logout
from django.core.mail import send_mail
from django.core.paginator import Paginator

from django.http import HttpResponse
from django.shortcuts import render, redirect

# Create your views here.
# /user/register
from django.urls import reverse
from django.views.generic import View
from django_redis import get_redis_connection
from itsdangerous import Serializer, SignatureExpired

from user.models import User
from user.models import Address
from goods.models import GoodsSKU

from order.models import OrderInfo, OrderGoods
from celery_tasks.tasks import send_register_active_email
from dailyfresh import settings

from utils.mixin import LoginRequiredMixin


# def register(request):
#     # 通过请求方式进行不同的数据处理并返回
#     if request.method == 'GET':
#         """
#         显示注册页面
#          """
#         return render(request, 'register.html')
#     else:
#         """
#             用户注册处理
#         """
#         username = request.POST.get("user_name")
#         password = request.POST.get("pwd")
#         email = request.POST.get("email")
#         allow = request.POST.get("allow")
#         # 数据校验
#         if not all([username, password, email]):
#             # 数据不完整功能
#             return render(request, 'register.html', {'errmsg': "输入的数据不完整"})
#         # 校验邮箱
#         if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
#             return render(request, 'register.html', {'errmsg': "邮箱格式不正确"})
#         if allow != 'on':
#             return render(request, 'register.html', {'errmsg': "请同意协议"})
#         # 校验用户名是否重复
#         try:
#             # 用户名存在
#             user = User.objects.get(username=username)
#         except User.DoesNotExist:
#             # 用户名不存在
#             user = None
#         if user:
#             # 用户存在
#             return render(request, 'register.html', {'errmsg': "用户已经存在"})
#         # 数据处理进行注册 这里我们使用了django自带的注册系统完善数据
#         user = User.objects.create_user(username, email, password)
#         # 激活问题
#         user.is_active = 0
#         user.save()
#         # 返回应答 跳转到首页
#         return redirect(reverse('goods:index'))


# # /user/register_handle
# def register(request):
#


# /register
class RegisterView(View):
    """
    类视图
    """

    def get(self, request):
        '''显示注册页面'''
        return render(request, 'register.html')

    def post(self, request):
        ''''进行注册数据处理'''
        username = request.POST.get("user_name")
        password = request.POST.get("pwd")
        email = request.POST.get("email")
        allow = request.POST.get("allow")
        # 数据校验
        if not all([username, password, email]):
            # 数据不完整功能
            return render(request, 'register.html', {'errmsg': "输入的数据不完整"})
        # 校验邮箱
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return render(request, 'register.html', {'errmsg': "邮箱格式不正确"})
        if allow != 'on':
            return render(request, 'register.html', {'errmsg': "请同意协议"})
        # 校验用户名是否重复
        try:
            # 用户名存在
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            # 用户名不存在
            user = None
        if user:
            # 用户存在
            return render(request, 'register.html', {'errmsg': "用户已经存在"})
        # 数据处理进行注册 这里我们使用了django自带的注册系统完善数据
        user = User.objects.create_user(username, email, password)
        # 激活问题
        user.is_active = 0
        user.save()

        # 激活过程 发送邮件
        # 加密用户身份信息 使用id为身份的唯一标识
        serializer = Serializer(settings.SECRET_KEY, 3600)
        info = {'confirm': user.id}
        token = serializer.dumps(info)
        token = token.decode('utf8')
        # 发邮件
        # subject = '天天生鲜欢迎你'
        # message = ''
        # # html_message有HTML样式的数据
        # html_message = '<h1>%s, 欢迎您成为天天生鲜注册会员</h1>请点击下面链接激活您的账户<br/><a href="http://127.0.0.1:8000/user/active/%s">http://127.0.0.1:8000/user/active/%s</a>' % (
        #     username, token, token)
        # sender = settings.EMAIL_FROM
        # receiver = [email]
        # send_mail(subject, message, sender, receiver, html_message=html_message)
        send_register_active_email.delay(email, username, token)
        # 返回应答 跳转到首页
        return redirect(reverse('goods:index'))


# active
class ActiveView(View):
    """用户激活"""

    def get(self, request, token):
        # 加密
        serializer = Serializer(settings.SECRET_KEY, 3600)
        try:
            info = serializer.loads(token)
            #  获取到待激活的用户id
            user_id = info['confirm']

            # 根据id获取到用户信息 更新激活状态并跳转到登陆界面
            user = User.objects.get(id=user_id)
            user.is_active = 1
            user.save()
            return redirect(reverse('user:login'))
        except SignatureExpired as e:
            # 激活链接过期
            return HttpResponse('激活链接已过期')
            # TODO 过期时需要返回给用户一个没有过期的链接


# /login
class LoginView(View):
    def get(self, request):
        # 判断是否记住用户名啦
        if 'username' in request.COOKIES:
            username = request.COOKIES.get('username')
            checked = ''
        else:
            username = ''
            checked = ''
        return render(request, 'login.html', {'username': username, 'checked': checked})

    def post(self, request):
        '''登录校验'''
        # 接受数据并处理
        username = request.POST.get('username')
        password = request.POST.get('pwd')
        # 校验
        if not all([username, password]):
            return render(request, 'login.html', {'errmsg': '数据不完整'})

        # 业务处理
        user = authenticate(username=username, password=password)
        if user is not None:
            # 判断激活状态
            if user.is_active:
                # 记住了用户信息在session中
                login(request, user)

                # 获取登录后需要跳转到的页面 默认跳转到首页
                next_url = request.GET.get('next', reverse('goods:index'))

                respone = redirect(next_url)  # HttpResponseRedirect
                # 记住用户名操作
                remeber = request.POST.get('remeber')
                if remeber == 'on':
                    # 记住用户名
                    respone.set_cookie('username', username, max_age=7 * 24 * 3600)
                else:
                    respone.delete_cookie('username')
                    # 响应
                    return respone
            else:
                return render(request, 'login.html', {'errmsg': '用户未激活'})
        else:
            return render(request, 'login.html', {'errmsg': '用户不存在'})


# /logout
class LogoutView(View):
    # 用户退出
    def get(self, request):
        logout(request)
        # 跳转到首页
        return redirect(reverse('goods:index'))


# /user
class UserInfoView(LoginRequiredMixin, View):
    """用户中心信息页"""
    """
    page = 'user'
    request.user
    如果用户未登录--AnonymousUser的一个实例
    登录：User类的实例
    request.user.is_authenticated
    """

    def get(self, request):
        # 用户的默认地址 显示
        user = request.user
        try:
            address = Address.objects.get_default_address(user)
        except:
            address =None

        # 浏览记录显示 Redis
        con = get_redis_connection('default')
        history_key = "history_%d" % user.id
        # 获取到用最新浏览的5个商品的id
        sku_ids = con.lrange(history_key, 0, 4)
        # 从数据库中查询用户浏览的商品信息
        goods_list = []
        for id in sku_ids:
            print('goods_id:', id)
            goods = GoodsSKU.objects.get(id=id)
            print('goods:', goods)
            goods_list.append(goods)

        context = {'page': 'user',
                   'address': address,
                   'goods_list': goods_list}
        print('context:', context)
        return render(request, 'user_center_info.html', context)


# user/order
class UserOrderView(LoginRequiredMixin, View):
    """用户中心信息页"""

    def get(self, request, page):
        # 获取到用户
        user = request.user
        orders = OrderInfo.objects.filter(user=user)
        for order in orders:
            order_skus = OrderGoods.objects.filter(order_id=order.order_id)
            for order_sku in order_skus:
                # 小计
                amount = order_sku.count * order_sku.price
                # d动态田间属性
                order_sku.amount = amount

            order.status_name = OrderInfo.ORDER_STATUS[order.order_status]
            print("order.order_status:", OrderInfo.ORDER_STATUS[3])
            order.order_skus = order_skus

        # 分页
        paginator = Paginator(orders, 10)

        try:
            page = int(page)
        except Exception as e:
            page = 1
        if page > paginator.num_pages:
            page = 1
        # 获取第page的page实例对象
        order_page = paginator.page(page)

        # todo: 进行页码的控制，页面上最多显示5个页码
        # 1.总页数小于5页，页面上显示所有页码
        # 2.如果当前页是前3页，显示1-5页
        # 3.如果当前页是后3页，显示后5页
        # 4.其他情况，显示当前页的前2页，当前页，当前页的后2页
        num_pages = paginator.num_pages
        if num_pages < 5:
            pages = range(1, num_pages + 1)
        elif page <= 3:
            pages = range(1, 6)
        elif num_pages - page <= 2:
            pages = range(num_pages - 4, num_pages + 1)
        else:
            pages = range(page - 2, page + 3)

        context = {'order_page': order_page,
                   'pages': pages,
                   'page': 'order'}

        # page 用于没有登录时跳转到登录界面登录后，在跳转回当前页面
        return render(request, 'user_center_order.html', context)


# /user/address
class AddressView(LoginRequiredMixin, View):
    """用户中心地址 页"""

    def get(self, request):
        user = request.user
        try:
            address = Address.objects.get_default_address(user)
            # address = Address.objects.get(user=user, is_default=True)
        except:
            address = None

        return render(request, 'user_center_site.html', {"page": "address", "address": address})

    def post(self, request):
        receiver = request.POST.get("receiver")
        addr = request.POST.get("addr")
        zip_code = request.POST.get("zip_code")
        phone = request.POST.get("phone")

        if not all([receiver, addr, phone]):
            return render(request, 'user_center_site.html', {'errmsg': '数据不完整'})

        if not re.match(r'^1[3|4|5|7|8][0-9]{9}$', phone):
            return render(request, 'user_center_site.html', {'errmsg': '手机格式不正确'})
        """
        业务逻辑：
        如果用户已经存在默认的收货地址，添加的地址不作为默认的收货地址，反之亦然。
        先获取到用户的所有的收货地址，查询是否存在收货地址
        """
        user = request.user
        try:
            address = Address.objects.get_default_address(user)
        except:
            address = None

        if address:
            is_default = False
        else:
            is_default = True

        Address.objects.create(user=user,
                               receiver=receiver,
                               addr=addr,
                               zip_code=zip_code,
                               phone=phone,
                               is_default=is_default)
        return redirect(reverse('user:address'))
